home *** CD-ROM | disk | FTP | other *** search
- UNIT AE2 ;
-
- {$R-}
- {$B-}
- {$I-}
- {$S+}
- {$V-}
-
- {-----------------------------------------------------------------------------}
- { This unit contains all movement procedures. }
- { All procedures operate on the current workspace (CurrentWs), }
- { unless specified otherwise. }
- {-----------------------------------------------------------------------------}
-
- INTERFACE
-
- USES Crt, Dos, AE0, AE1 ;
-
- PROCEDURE Home (VAR P : Position) ;
- PROCEDURE EndOfLine (VAR P : Position) ;
- PROCEDURE CalculateColnr (VAR P : position) ;
- PROCEDURE SkipDown (VAR P : Position ; Distance : WORD) ;
- PROCEDURE SkipUp (VAR P : Position ; Distance : WORD) ;
- PROCEDURE WordDown (VAR P : Position) ;
- PROCEDURE WordUp (VAR P : Position) ;
- PROCEDURE LineDown (VAR P : Position) ;
- PROCEDURE LineUp (VAR P : Position) ;
- PROCEDURE SearchUp (Target : STRING ; VAR P : Position ; LimitIndex : WORD) ;
- PROCEDURE SearchDown (Target : STRING ; VAR P : Position ; LimitIndex : WORD) ;
- PROCEDURE SearchString (Target : STRING ; VAR P : Position) ;
- PROCEDURE MatchBracketsDown (OpenBracket, CloseBracket : CHAR ; VAR P : Position) ;
- PROCEDURE MatchBracketsUp (OpenBracket, CloseBracket : CHAR ; VAR P : Position) ;
-
- IMPLEMENTATION
-
- {-----------------------------------------------------------------------------}
- { Sets P to the first column of the line it is pointing to }
- {-----------------------------------------------------------------------------}
-
- PROCEDURE Home (VAR P : Position) ;
-
- BEGIN
- DEC (P.Index, P.Colnr - 1) ;
- P.Colnr := 1 ;
- END ;
-
- {-----------------------------------------------------------------------------}
- { Sets P to the last column of the current line (line separator or }
- { end of file) }
- {-----------------------------------------------------------------------------}
-
- PROCEDURE EndOfLine (VAR P : Position) ;
-
- BEGIN
- WITH CurrentWs DO
- BEGIN
- WHILE (Buffer^ [P.Index] <> LF) AND
- (P.Index < Buffersize) DO
- BEGIN
- INC (P.Index) ;
- INC (P.Colnr) ;
- END ;
- IF (Buffer^ [P.Index - 1] = CR) AND
- (Buffer^ [P.Index] = LF)
- THEN BEGIN
- DEC (P.Index) ;
- DEC (P.Colnr) ;
- END ;
- END ; { of with }
- END ;
-
- {-----------------------------------------------------------------------------}
- { Re-calculates the column number by searching for a previous line feed }
- {-----------------------------------------------------------------------------}
-
- PROCEDURE CalculateColnr (VAR P : position) ;
-
- BEGIN
- WITH CurrentWs DO
- BEGIN
- IF P.Linenr = 1
- THEN P.Colnr := P.Index
- ELSE BEGIN
- P.Colnr := 1 ;
- WHILE (Buffer^ [P.Index - P.Colnr] <> LF) DO INC (P.Colnr) ;
- END ;
- END ;
- END ;
-
- {-----------------------------------------------------------------------------}
- { Skips P <Distance> positions downward, adjusting line and column number. }
- { If the end of the buffer is reached, the procedure stops. }
- {-----------------------------------------------------------------------------}
-
- PROCEDURE SkipDown (VAR P : Position ; Distance : WORD) ;
-
- VAR Counter : WORD ;
-
- BEGIN
- WITH CurrentWs DO
- BEGIN
- IF (P.Index + Distance) > BufferSize
- THEN Distance := BufferSize - P.Index ;
- FOR Counter := 1 TO Distance DO
- BEGIN
- IF Buffer^ [P.Index] = LF
- THEN INC (P.Linenr) ;
- INC (P.Index) ;
- END ;
- CalculateColnr (P) ;
- END ;
- END ;
-
- {-----------------------------------------------------------------------------}
- { Skips P <Distance> positions upward, adjusting line and column number. }
- { If the start of the buffer is reached, the procedure stops. }
- {-----------------------------------------------------------------------------}
-
- PROCEDURE SkipUp (VAR P : Position ; Distance : WORD) ;
-
- VAR Counter : WORD ;
-
- BEGIN
- WITH CurrentWs DO
- BEGIN
- IF Distance < P.Colnr
- THEN BEGIN
- { P will remain within current line }
- DEC (P.Colnr, Distance) ;
- DEC (P.Index, Distance) ;
- END
- ELSE BEGIN
- IF P.Index <= Distance
- THEN BEGIN
- { go to start of buffer }
- P.Index := 1 ;
- P.Linenr := 1 ;
- END
- ELSE FOR Counter := 1 TO Distance DO
- BEGIN
- DEC (P.Index) ;
- IF Buffer^ [P.Index] = LF
- THEN DEC (P.Linenr) ;
- END ;
- CalculateColnr (P) ;
- END ;
- END ;
- END ;
-
- {-----------------------------------------------------------------------------}
- { Skips P downward until the beginning of the next word in the text. }
- {-----------------------------------------------------------------------------}
-
- PROCEDURE WordDown (VAR P : Position) ;
-
- BEGIN
- WITH CurrentWs DO
- BEGIN
- WHILE NOT ( (Buffer^ [P.Index] IN WordDelimiters) OR
- (P.Index = BufferSize) ) DO
- BEGIN
- INC (P.Colnr) ;
- INC (P.Index) ;
- END ;
- WHILE (Buffer^ [P.Index] IN WordDelimiters) AND
- (P.Index < BufferSize) DO
- BEGIN
- IF Buffer^ [P.Index] = LF
- THEN BEGIN
- INC (P.Linenr) ;
- P.Colnr := 1 ;
- END
- ELSE IF NOT ( (Buffer^ [P.Index] = CR) AND
- (Buffer^ [P.Index + 1] = LF) )
- THEN INC (P.Colnr) ;
- INC (P.Index) ;
- END ;
- END ;
- END ;
-
- {-----------------------------------------------------------------------------}
- { Skips P upward until the beginning of the previous word in the text. }
- {-----------------------------------------------------------------------------}
-
- PROCEDURE WordUp (VAR P : Position) ;
-
- BEGIN
- WITH CurrentWs DO
- BEGIN
- IF P.Index > 1
- THEN BEGIN
- REPEAT DEC (P.Index) ;
- IF Buffer^ [P.Index] = LF
- THEN DEC (P.Linenr) ;
- UNTIL ( (NOT (Buffer^ [P.Index] IN WordDelimiters) ) OR
- (P.Index = 1) ) ;
- WHILE ( (NOT (Buffer^ [P.Index] IN WordDelimiters) ) AND
- (P.Index > 0) ) DO
- BEGIN
- DEC (P.Index) ;
- END ;
- INC (P.Index) ;
- CalculateColnr (P) ;
- END ;
- END ;
- END ;
-
- {-----------------------------------------------------------------------------}
- { Skips P downward to the first column of the next line. }
- { If the end of the buffer is reached, the procedure stops. }
- {-----------------------------------------------------------------------------}
-
- PROCEDURE LineDown (VAR P : Position) ;
-
- VAR StartIndex : WORD ;
-
- BEGIN
- StartIndex := P.Index ;
- WITH CurrentWs DO
- BEGIN
- WHILE (Buffer^ [P.Index] <> LF) AND (P.Index < BufferSize) DO
- INC (P.Index) ;
- IF (Buffer^ [P.Index] = LF)
- THEN BEGIN
- INC (P.Index) ;
- P.Colnr := 1 ;
- INC (P.Linenr) ;
- END
- ELSE INC (P.Colnr, P.Index - StartIndex) ;
- END ;
- END ;
-
- {-----------------------------------------------------------------------------}
- { Skips P upward to the first column of the previous line. }
- { If the start of the buffer is reached, the procedure stops. }
- {-----------------------------------------------------------------------------}
-
- PROCEDURE LineUp (VAR P : Position) ;
-
- BEGIN
- IF P.Linenr <= 2
- THEN BEGIN
- P.Index := 1 ;
- P.Linenr := 1 ;
- END
- ELSE WITH CurrentWs DO
- BEGIN
- { go to line feed before start of current line }
- DEC (P.Index, P.Colnr) ;
- { find start of line }
- WHILE (Buffer^ [P.Index - 1] <> LF) DO
- DEC (P.Index) ;
- DEC (P.Linenr) ;
- END ;
- P.Colnr := 1 ;
- END ;
-
- {-----------------------------------------------------------------------------}
- { Searches downward for the string <Target>. On exit, P points to the first }
- { character of the string in the text buffer, if the string is found before }
- { index <LimitIndex> is reached. Otherwise, P will point to <LimitIndex>. }
- { The value of global variable Found will be set accordingly. }
- {-----------------------------------------------------------------------------}
-
- PROCEDURE SearchDown (Target : STRING ; VAR P : Position ; LimitIndex : WORD) ;
-
- VAR Counter : BYTE ;
-
- BEGIN
- Found := FALSE ;
- WITH CurrentWs DO
- BEGIN
- IF IgnoreCase
- THEN BEGIN
- { case-insensitive search }
- Target := UpperCase (Target) ;
- WHILE (NOT Found) AND (P.Index <= LimitIndex) DO
- BEGIN
- { search text for first character of Target }
- REPEAT IF Buffer^ [P.Index] = LF
- THEN INC (P.Linenr) ;
- INC (P.Index) ;
- UNTIL (UPCASE (Buffer^ [P.Index]) = Target [1]) OR
- (P.Index > LimitIndex) ;
- Counter := 2 ;
- { check if following characters are equal to Target }
- WHILE (UPCASE (Buffer^ [P.Index + Counter - 1]) = Target [Counter])
- AND (Counter <= LENGTH (Target) ) DO
- INC (Counter) ;
- Found := (Counter > LENGTH (Target) ) AND
- ( (P.Index + LENGTH (Target) - 1) <= LimitIndex) ;
- IF WholeWords
- THEN Found := Found AND
- (Buffer^ [P.Index-1] IN WordSeparators) AND
- (Buffer^ [P.Index+Counter-1] IN WordSeparators) ;
- END ; { of while }
- END { of case-insensitive search }
- ELSE BEGIN
- { normal search }
- WHILE (NOT Found) AND (P.Index <= LimitIndex) DO
- BEGIN
- { search text for first character of Target }
- REPEAT IF Buffer^ [P.Index] = LF
- THEN INC (P.Linenr) ;
- INC (P.Index) ;
- UNTIL (Buffer^ [P.Index] = Target [1]) OR
- (P.Index > LimitIndex) ;
- Counter := 2 ;
- { check if following characters are equal to Target }
- WHILE (Buffer^ [P.Index + Counter - 1] = Target [Counter]) AND
- (Counter <= LENGTH (Target) ) DO
- INC (Counter) ;
- Found := (Counter > LENGTH (Target) ) AND
- ( (P.Index + LENGTH (Target) - 1) <= LimitIndex) ;
- IF WholeWords
- THEN Found := Found AND
- (Buffer^ [P.Index-1] IN WordSeparators) AND
- (Buffer^ [P.Index+Counter-1] IN WordSeparators) ;
- END ; { of while }
- END ; { of normal search }
- CalculateColnr (P) ;
- END ; { of with }
- END ; { of procedure }
-
- {-----------------------------------------------------------------------------}
- { Searches upward for the string <Target>. On exit, P points to the first }
- { character of the string in the text buffer, if the string is found before }
- { index <LimitIndex> is reached. Otherwise, P will point to <LimitIndex>. }
- { The value of global variable Found will be set accordingly. }
- {-----------------------------------------------------------------------------}
-
- PROCEDURE SearchUp (Target : STRING ; VAR P : Position ; LimitIndex : WORD) ;
-
- VAR Counter : WORD ;
-
- BEGIN
- Found := FALSE ;
- WITH CurrentWs DO
- BEGIN
- IF IgnoreCase
- THEN BEGIN
- { case-insensitive search }
- Target := UpperCase (Target) ;
- WHILE (NOT Found) AND (P.Index >= LimitIndex) DO
- BEGIN
- { search text for first character of Target }
- REPEAT DEC (P.Index) ;
- IF Buffer^ [P.Index] = LF
- THEN DEC (P.Linenr) ;
- UNTIL (UPCASE (Buffer^ [P.Index]) = Target [1]) OR
- (P.Index < LimitIndex) ;
- Counter := 2 ;
- { check if following characters are equal to Target }
- WHILE (UPCASE (Buffer^ [P.Index + Counter - 1]) =
- Target [Counter]) AND
- (Counter <= LENGTH (Target) ) DO
- INC (Counter) ;
- Found := (Counter > LENGTH (Target) ) AND
- (P.Index >= LimitIndex) ;
- IF WholeWords
- THEN Found := Found AND
- (Buffer^ [P.Index-1] IN WordSeparators) AND
- (Buffer^ [P.Index+Counter-1] IN WordSeparators) ;
- END ; { of while }
- END { of case-insensitive search }
- ELSE BEGIN
- { normal search }
- WHILE (NOT Found) AND (P.Index >= LimitIndex) DO
- BEGIN
- { search text for first character of Target }
- REPEAT DEC (P.Index) ;
- IF Buffer^ [P.Index] = LF
- THEN DEC (P.Linenr) ;
- UNTIL (Buffer^ [P.Index] = Target [1]) OR
- (P.Index < LimitIndex) ;
- Counter := 2 ;
- { check if following characters are equal to Target }
- WHILE (Buffer^ [P.Index + Counter - 1] = Target [Counter]) AND
- (Counter <= LENGTH (Target) ) DO
- INC (Counter) ;
- Found := (Counter > LENGTH (Target) ) AND
- (P.Index >= LimitIndex) ;
- IF WholeWords
- THEN Found := Found AND
- (Buffer^ [P.Index-1] IN WordSeparators) AND
- (Buffer^ [P.Index+Counter-1] IN WordSeparators) ;
- END ; { of while }
- END { of normal search } ;
- CalculateColnr (P) ;
- END ; { of with }
- END ; { of procedure }
-
- {-----------------------------------------------------------------------------}
- { Performs a general search for <Target> according to the search options }
- { that are stored in global boolean variables. (Searching is done by calling }
- { SearchDown or SearchUp.) If Target is found, P will point to the first }
- { character. }
- {-----------------------------------------------------------------------------}
-
- PROCEDURE SearchString (Target : STRING ; VAR P : Position) ;
-
- BEGIN
- Found := FALSE ;
- IF LENGTH (Target) > 0
- THEN BEGIN
- WITH CurrentWs DO
- BEGIN
- IF ReverseSearch
- THEN BEGIN
- SearchUp (Target, P, 1) ;
- END
- ELSE BEGIN
- SearchDown (Target, P, BufferSize - 1) ;
- END ;
- END ; { of with }
- END ;
- END ;
-
- {-----------------------------------------------------------------------------}
- { Searches downward for an occurrence of CloseBracket in the buffer, }
- { matching the OpenBracket that P is assumed to point at when the procedure }
- { is called. If no matching bracket is found, P will point to the end of the }
- { buffer, and Found is set to False. }
- {-----------------------------------------------------------------------------}
-
- PROCEDURE MatchBracketsDown (OpenBracket, CloseBracket : CHAR ; VAR P : Position) ;
-
- VAR Level : INTEGER ;
- { Level keeps track of the nesting level of the brackets }
-
- BEGIN
- Level := 1 ;
- WITH CurrentWs DO
- BEGIN
- WHILE (Level > 0) AND (P.Index < BufferSize) DO
- BEGIN
- IF Buffer^ [P.Index] = LF
- THEN INC (P.Linenr) ;
- INC (P.Index) ;
- IF Buffer^ [P.Index] = OpenBracket THEN INC (Level) ;
- IF Buffer^ [P.Index] = CloseBracket THEN DEC (Level) ;
- END ; { of while }
- CalculateColnr (P) ;
- END ;
- Found := (Level = 0) ;
- END ;
-
- {-----------------------------------------------------------------------------}
- { Searches upward for an occurrence of CloseBracket in the buffer, matching }
- { the OpenBracket that P is assumed to point at when the procedure is called. }
- { If no matching bracket is found, P will point to the start of the }
- { buffer, and Found is set to False. }
- {-----------------------------------------------------------------------------}
-
- PROCEDURE MatchBracketsUp (OpenBracket, CloseBracket : CHAR ; VAR P : Position) ;
-
- VAR Level : INTEGER ;
- { Level keeps track of the nesting level of the brackets }
-
- BEGIN
- Level := - 1 ;
- WITH CurrentWs DO
- BEGIN
- WHILE (Level < 0) AND (P.Index > 1) DO
- BEGIN
- DEC (P.Index) ;
- IF Buffer^ [P.Index] = LF
- THEN DEC (P.Linenr) ;
- IF Buffer^ [P.Index] = OpenBracket THEN INC (Level) ;
- IF Buffer^ [P.Index] = CloseBracket THEN DEC (Level) ;
- END ; { of while }
- CalculateColnr (P) ;
- END ;
- Found := (Level = 0) ;
- END ;
-
- {-----------------------------------------------------------------------------}
-
- END.